#pragma once

#include <iostream>
#include <string>
#include <vector>
#include<pthread.h>
#include "InetAddr.hpp"
#include"Threadpool.hpp"
#include"LockGuard.hpp"
class MessageRoute
{
private:
    void AddUser(InetAddr &who)
    {
        LockGuard lg(&mutex);
        for(auto&user:_online_users)
        {
            if(who==user)return;
        }
        _online_users.push_back(who);
    }
    void DelUser(InetAddr &who)
    {
        LockGuard lg(&mutex);
        for(auto iter=_online_users.begin();iter!=_online_users.end();iter++)
        {
            if(*iter==who)
            {
                _online_users.erase(iter);
                break;
            }
        }
    }

void Tothreadpool(int sockfd, std::string message, InetAddr who)
{
    LockGuard lg(&mutex);
    for (auto &user : _online_users)
        {
            std::string what='['+who.Ip()+':'+std::to_string(who.Port())+']'+'#'+message;
            struct sockaddr_in towho=user.Addr();
            sendto(sockfd, what.c_str(), what.size(), 0, (struct sockaddr *)&towho, sizeof(struct sockaddr_in));
        }
}
public:
MessageRoute()
{
    pthread_mutex_init(&mutex,nullptr);
}
    void Route(int sockfd, std::string message, InetAddr who)
    {
        AddUser(who);
        if (message == "Q" || message == "quit")
            DelUser(who);
        ThreadPool<function<void()>>::Getinstance()->Enqueue(std::bind(&MessageRoute::Tothreadpool,this,sockfd,message,who));
    }
~MessageRoute()
{
    pthread_mutex_destroy(&mutex);
}
private:
    std::vector<InetAddr> _online_users;
    pthread_mutex_t mutex;
};